package com.ququ.syb.entrance.service;

import com.alibaba.fastjson.JSON;
import com.ququ.common.exception.QuQuException;
import com.ququ.common.result.Result;
import com.ququ.syb.common.constant.EncryptTypeConstant;
import com.ququ.syb.common.pojo.AccountInfo;
import com.ququ.syb.entrance.fegin.AccountBusinessFegin;
import com.ququ.syb.entrance.fegin.ApplicationFegin;
import com.ququ.syb.entrance.po.RequestData;
import com.ququ.syb.entrance.utils.EncryptUtil;
import com.ququ.syb.entrance.utils.SignUtil;
import com.ququ.syb.entrance.vo.SybResult;
import com.ququ.syb.entrance.vo.SybResultData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Service
public class SecurityService {

    private Logger logger = LoggerFactory.getLogger(SecurityService.class);
    @Autowired
    private AccountBusinessFegin accountBusinessFegin;
    @Autowired
    private ApplicationFegin applicationFegin;

    /**
     * 接口数据解密
     * @param data
     * @param token
     * @param encryptType
     * @return
     */
    public String decrypt(String data, String token, Integer encryptType){
        String plainText = null;
        logger.debug("解密之前密文:{},解密方式:{}",data,encryptType);
        switch (encryptType){
            case EncryptTypeConstant.PLAINTEXT:
                plainText = data;
                break;
            case EncryptTypeConstant.AES:
                try {
                    plainText = EncryptUtil.decrypt(data,token);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new QuQuException(-1,"数据解密失败");
                }
                break;
            default:
                throw new QuQuException(-1,"不支持这种加密方式");
        }
        logger.debug("解密后的明文:{}",plainText);
        return plainText;
    }

    public String decrypt(String data, String accountid) {
        String token = accountBusinessFegin.getToken(accountid).getData().substring(8,24);
        return decrypt(data,token,EncryptTypeConstant.AES);
    }

    /**
     * 返回数据加密
     * @param data
     * @param accountid
     * @param encryptType
     * @return
     */
    public String encrypt(String data, String accountid, Integer encryptType){
        String encryptData = null;
        logger.debug("加密之前的明文:{},账户:{}",data,accountid);
        switch (encryptType){
            case EncryptTypeConstant.PLAINTEXT:
                encryptData = data;
                break;
            case EncryptTypeConstant.AES:
                String token = accountBusinessFegin.getToken(accountid).getData().substring(8,24);
                if (token == null)
                    throw new QuQuException(-1,"生意宝账户不存在");
                try {
                    encryptData = EncryptUtil.encrypt(data,token);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;
            default:
                throw new QuQuException(-1,"不支持这种加密方式");
        }
        logger.debug("加密后的密文:{}",encryptData);
        return encryptData;
    }


    /**
     * 签名
     * @param data
     * @param appcode
     * @return
     */
    public String sign(Map<String,Object> data,String appcode){
        String signKey = applicationFegin.getApplicationKey(appcode).getData();
        if (signKey == null)
            throw new QuQuException(-1,"应用代码不存在");
        return SignUtil.sign(signKey,data);
    }

    /**
     * 签名
     * @param data
     * @param appcode
     * @return
     */
    public String sign(Object data,String appcode){
        String signKey = applicationFegin.getApplicationKey(appcode).getData();
        if (signKey == null)
            throw new QuQuException(-1,"应用代码不存在");
        return SignUtil.sign(signKey,data);
    }

    /**
     * 验签
     * @param data
     * @param appcode
     * @param sign
     * @return
     */
    public boolean verifySign(String data,String appcode,String sign){
        String signKey = applicationFegin.getApplicationKey(appcode).getData();
        if (signKey == null)
            throw new QuQuException(-1,"应用代码不存在");
        return SignUtil.verifySign(signKey,data,sign);
    }

    /**
     * 从接口获取参数
     * @param requestData
     * @return
     */
    public Map<String,Object> getParametersMap (RequestData<String> requestData){
        AccountInfo accountInfo = accountBusinessFegin.getAccountInfo(requestData.getAccountid()).getData();
        if (accountInfo == null)
            throw new QuQuException(-1,"账户不存在");
        String token = accountInfo.getToken().substring(8,24);
        String plantext = decrypt(requestData.getData(),token,requestData.getEncryptType());
        Map<String,Object> dataMap = plantext==null?new HashMap<>():JSON.parseObject(plantext,Map.class);
        dataMap.put("appcode",requestData.getAppcode());
        dataMap.put("requestAccountid",requestData.getAccountid());
        if (!verifySign(plantext==null?"":plantext,requestData.getAppcode(),requestData.getSign()))
            throw new QuQuException(-1,"验签失败");
        if (!requestData.getAppcode().equals(accountInfo.getAppcode()))
            throw new QuQuException(-1,"账户不属于本应用");
        if (accountInfo.getStatus() != 1)
            throw new QuQuException(-1,"本账户已经冻结");
        return dataMap;
    }


    /**
     * 生成返回的结果
     * @param data
     * @param requestData
     * @return
     */
    public  SybResult buildSybResult(Object data, RequestData<String> requestData){
//        String encryptData = encrypt(JSON.toJSONString(data),requestData.getAccountid(),requestData.getEncryptType());
//        String jsonData = JSON.toJSONString(data);
        return new SybResult(new SybResultData(requestData.getAccountid(),data),
                sign(data,requestData.getAppcode()));
    }

}
